package top.wshape1.easyscan.data;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import androidx.annotation.Nullable;

import java.util.ArrayList;
import java.util.List;

import top.wshape1.easyscan.R;
import top.wshape1.easyscan.entity.CustomRule;

/**
 * @author Wshape1
 * @version 1.0
 * @description
 * @since 2023-05-22
 */
public class SettingSQLiteHelper extends SQLiteOpenHelper {

    private static final String DATABASE_NAME = "easy_scan_setting.db";
    private static final int DATABASE_VERSION = 1;

    private final String TABLE_NAME = "custom_rule";

    /**
     * type: 0 contain; 1 startWith; 2 endWith; 3 regex
     */
    private final String[] COLUMNS;

    private final SQLiteDatabase readableDatabase;

    private final SQLiteDatabase writableDatabase;

    public SettingSQLiteHelper(@Nullable Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        COLUMNS = new String[]{"id", "`type`", "match_string", "package_name", "class_name", "`order`", "description"};
        readableDatabase = getReadableDatabase();
        writableDatabase = getWritableDatabase();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE " + TABLE_NAME + "(" +
                COLUMNS[0] + " INTEGER PRIMARY KEY AUTOINCREMENT," +
                COLUMNS[1] + " INTEGER DEFAULT 0," +
                COLUMNS[2] + " TEXT NOT NULL," +
                COLUMNS[3] + " TEXT NOT NULL," +
                COLUMNS[4] + " TEXT NOT NULL," +
                COLUMNS[5] + " INTEGER DEFAULT 0," +
                COLUMNS[6] + " TEXT" +
                ")");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

    public int count() {
        int count = 0;
        try (Cursor cursor = readableDatabase.query(TABLE_NAME, new String[]{"COUNT(*)"}, null, null, null, null, null)
        ) {
            if (cursor.moveToFirst()) {
                count = cursor.getInt(0);
            }
        }
        return count;
    }

    /**
     * 通过查询数据库返回的cursor来获得CustomRule示例
     *
     * @param cursor Database cursor
     * @return customRule get by cursor
     */
    private CustomRule instanceByCursor(Cursor cursor) {
        if (cursor != null)
            return new CustomRule(
                    cursor.getInt(0),
                    cursor.getInt(1),
                    cursor.getString(2),
                    cursor.getString(3),
                    cursor.getString(4),
                    cursor.getInt(5),
                    cursor.getString(6)
            );
        return null;
    }

    /**
     * 获取所有customRule
     *
     * @return list of all customRule from database
     */
    public List<CustomRule> list() {
        List<CustomRule> list = new ArrayList<>();
        try (Cursor cursor = readableDatabase.query(TABLE_NAME, COLUMNS, null, null, null, null, COLUMNS[5] + " ASC")
        ) {
            while (cursor.moveToNext()) {
                list.add(instanceByCursor(cursor));
            }
        }
        return list;
    }

    /**
     * get customRule by id
     *
     * @param id customRule's id
     * @return customRule
     */
    public CustomRule getById(int id) {
        CustomRule customRule = null;
        try (Cursor cursor = readableDatabase.query(TABLE_NAME, COLUMNS, COLUMNS[0] + " = ?", new String[]{String.valueOf(id)}, null, null, null)) {
            if (cursor.moveToFirst()) {
                customRule = instanceByCursor(cursor);
            }
        }
        return customRule;
    }

    /**
     * add a customRule to database
     *
     * @param customRule customRule you want to add
     * @return 新插入的row ID，出错则返回-1
     */
    public long insert(CustomRule customRule) {
        ContentValues contentValues = new ContentValues();
        contentValues.put(COLUMNS[1], customRule.getType());
        contentValues.put(COLUMNS[2], customRule.getMatchString());
        contentValues.put(COLUMNS[3], customRule.getPackageName());
        contentValues.put(COLUMNS[4], customRule.getClassName());
        contentValues.put(COLUMNS[5], customRule.getOrder());
        contentValues.put(COLUMNS[6], customRule.getDescription());
        return writableDatabase.insert(TABLE_NAME, null, contentValues);
    }

    /**
     * 移除一个customRule
     *
     * @param id customRule's id
     * @return 影响的行数
     */
    public int remove(int id) {
        return writableDatabase.delete(TABLE_NAME, COLUMNS[0] + " = ?", new String[]{String.valueOf(id)});
    }

    /**
     * 通过id更新customRule
     *
     * @param customRule 必须带有id
     * @return 影响的行数
     */
    public int update(CustomRule customRule) {
        if (customRule == null || customRule.getId() == null)
            return 0;
        ContentValues contentValues = new ContentValues();
        if (customRule.getType() != null)
            contentValues.put(COLUMNS[1], customRule.getType());
        if (customRule.getMatchString() != null)
            contentValues.put(COLUMNS[2], customRule.getMatchString());
        if (customRule.getPackageName() != null)
            contentValues.put(COLUMNS[3], customRule.getPackageName());
        if (customRule.getClassName() != null)
            contentValues.put(COLUMNS[4], customRule.getClassName());
        if (customRule.getOrder() != null)
            contentValues.put(COLUMNS[5], customRule.getOrder());
        if (customRule.getDescription() != null)
            contentValues.put(COLUMNS[6], customRule.getDescription());
        return writableDatabase.update(TABLE_NAME, contentValues, COLUMNS[0] + " = ?", new String[]{String.valueOf(customRule.getId())});
    }

}
